export namespace BitMath
{

    export class ColorHSV
    {
        h: number = 0;//0~255 //色度
        s: number = 0;        //彩度
        v: number = 0;        //亮度，這個是非綫性的亮度，取了最大值

        CompareTo(test: ColorHSV): number
        {
            //权重 色度，彩度，亮度是一样的
            const rightH =1;
            const rightS =1;
            const rightV =1;
        
            return Math.abs(test.h - this.h)*rightH + Math.abs(test.s - this.s)*rightS + Math.abs(test.v - this.v)*rightV;
        }
    }
    export class Color32
    {
        r: number = 0;//0~255
        g: number = 0;
        b: number = 0;
        a: number = 255;

        toHSV(hsv: ColorHSV)
        {

            let min = Math.min(this.r, this.g, this.b);
            let max = Math.max(this.r, this.g, this.b);
            let delta = max - min;

            hsv.v = max;
            if (delta > 0)
                hsv.s = ((delta / max) * 255) | 0;
            else
            {
                hsv.s = 0;
                hsv.h = -1;  //純黑到純白的顔色 
                return;
            }

            if (this.r == max)
                hsv.h = (this.g - this.b) / delta;     // between yellow & magenta
            else if (this.g == max)
                hsv.h = 2 + (this.b - this.r) / delta; // between cyan & yellow
            else
                hsv.h = 4 + (this.b - this.g) / delta; // between magenta & cyan
            //從-1 到 5 映射到 0~255
            if (hsv.h < 0)
                hsv.h += 6;
            hsv.h = (hsv.h / 6 * 255) | 0;

        }

    }

    export class Rect
    {
        constructor(x:number=0,y:number=0,w:number=0,h:number=0)
        {
            this.x=x;
            this.y=y;
            this.w=w;
            this.h=h;
        }
        x: number = 0;
        y: number = 0;
        w: number = 0;
        h: number = 0;
    }

    export class LimitRect
    {
        public xmin: number = 0;
        public ymin: number = 0;
        public xmax: number = 0;
        public ymax: number = 0;
    }

    export class OutPalette
    {
        palette: Color32[] = [];
        paletteStr: string[] = [];//调色板的颜色值 css 格式 "#ffffff00" rgba
        openTag: Uint8Array = new Uint8Array(256);//哪些颜色是启用的 bool[] ,0=关闭，1=打开
        transparentIndex: number = 0;//透明色是哪个 


        ///寻找最接近的颜色值
        GetNearrestIndex(color: Color32): number
        {
            let hsv: ColorHSV = new ColorHSV();
            let hsvTest: ColorHSV = new ColorHSV();
            color.toHSV(hsv);
            let pickIndex: number = -1;
            let minDelta: number = 255;
            for (var i = 0; i < this.palette.length; i++)
            {
                this.palette[i].toHSV(hsvTest);
                let delta = hsv.CompareTo(hsvTest);
                if (delta < minDelta)
                {
                    minDelta = delta;
                    pickIndex = i;
                }
            }

            return pickIndex;
        }
        GetColor(index: number): Color32
        {
            return this.palette[index];
        }
        GetColorStr(index: number): string
        {
            return this.paletteStr[index];
        }
        static Init(colors: Color32[], transparentIndex: number): OutPalette
        {
            let p = new OutPalette();
            p.transparentIndex = transparentIndex;
            for (var i = 0; i < colors.length; i++)
            {
                let color = colors[i];
                let colorstr = OutPalette.GetColorStr(color);

                p.palette.push(color);
                p.paletteStr.push(colorstr);
                p.openTag[i] = 1;
            }
            return p;
        }
        static GetColorStr(color: Color32): string
        {
            let cs = "#";
            let hex = color.r.toString(16);
            if (hex.length == 1)
                cs += "0";
            cs += hex;

            hex = color.g.toString(16);
            if (hex.length == 1)
                cs += "0";
            cs += hex;

            hex = color.b.toString(16);
            if (hex.length == 1)
                cs += "0";
            cs += hex;

            hex = color.a.toString(16);
            if (hex.length == 1)
                cs += "0";
            cs += hex;


            return cs;
        }
    }

}